package models

import (
	"fmt"
	"time"
	"github.com/gin-gonic/gin"
)

type TestAnswer struct {
	Tas_id int `gorm:"column:tas_id"`
	Sno       string    `gorm:"column:sno"`
	Test_time time.Time `gorm:"column:test_time"`
	Answer_1  string    `gorm:"column:answer_1"`
	Answer_2  string    `gorm:"column:answer_2"`
	Answer_3  string    `gorm:"column:answer_3"`
	Answer_4  string    `gorm:"column:answer_4"`
	Answer_5  string    `gorm:"column:answer_5"`
	Answer_6  string    `gorm:"column:answer_6"`
	Answer_7  string    `gorm:"column:answer_7"`
	Answer_8  string    `gorm:"column:answer_8"`
	Answer_9  string    `gorm:"column:answer_9"`
	Answer_10 string    `gorm:"column:answer_10"`
	Answer_11 string    `gorm:"column:answer_11"`
	Answer_12 string    `gorm:"column:answer_12"`
	Answer_13 string    `gorm:"column:answer_13"`
	Answer_14 string    `gorm:"column:answer_14"`
	Answer_15 string    `gorm:"column:answer_15"`
	Answer_16 string    `gorm:"column:answer_16"`
	Answer_17 string    `gorm:"column:answer_17"`
	Answer_18 string    `gorm:"column:answer_18"`
	Answer_19 string    `gorm:"column:answer_19"`
	Answer_20 string    `gorm:"column:answer_20"`
	Answer_21 string    `gorm:"column:answer_21"`
	Answer_22 string    `gorm:"column:answer_22"`
	Answer_23 string    `gorm:"column:answer_23"`
	Answer_24 string    `gorm:"column:answer_24"`
	Answer_25 string    `gorm:"column:answer_25"`
	Answer_26 string    `gorm:"column:answer_26"`
	Answer_27 string    `gorm:"column:answer_27"`
	Answer_28 string    `gorm:"column:answer_28"`
	Answer_29 string    `gorm:"column:answer_29"`
	Answer_30 string    `gorm:"column:answer_30"`
	Answer_31 string    `gorm:"column:answer_31"`
	Answer_32 string    `gorm:"column:answer_32"`
	Answer_33 string    `gorm:"column:answer_33"`
	Answer_34 string    `gorm:"column:answer_34"`
	Answer_35 string    `gorm:"column:answer_35"`
	Answer_36 string    `gorm:"column:answer_36"`
	Answer_37 string    `gorm:"column:answer_37"`
	Answer_38 string    `gorm:"column:answer_38"`
	Answer_39 string    `gorm:"column:answer_39"`
	Answer_40 string    `gorm:"column:answer_40"`
	Answer_41 string    `gorm:"column:answer_41"`
	Answer_42 string    `gorm:"column:answer_42"`
	Answer_43 string    `gorm:"column:answer_43"`
	Answer_44 string    `gorm:"column:answer_44"`
	Answer_45 string    `gorm:"column:answer_45"`
	Answer_46 string    `gorm:"column:answer_46"`
	Answer_47 string    `gorm:"column:answer_47"`
	Answer_48 string    `gorm:"column:answer_48"`
	Answer_49 string    `gorm:"column:answer_49"`
	Answer_50 string    `gorm:"column:answer_50"`
	Answer_51 string    `gorm:"column:answer_51"`
	Answer_52 string    `gorm:"column:answer_52"`
	Answer_53 string    `gorm:"column:answer_53"`
	Answer_54 string    `gorm:"column:answer_54"`
	Answer_55 string    `gorm:"column:answer_55"`
	Answer_56 string    `gorm:"column:answer_56"`
	Answer_57 string    `gorm:"column:answer_57"`
	Answer_58 string    `gorm:"column:answer_58"`
	Answer_59 string    `gorm:"column:answer_59"`
	Answer_60 string    `gorm:"column:answer_60"`
	Answer_61 string    `gorm:"column:answer_61"`
	Answer_62 string    `gorm:"column:answer_62"`
	Answer_63 string    `gorm:"column:answer_63"`
	Answer_64 string    `gorm:"column:answer_64"`
	Answer_65 string    `gorm:"column:answer_65"`
	Answer_66 string    `gorm:"column:answer_66"`
	Answer_67 string    `gorm:"column:answer_67"`
	Answer_68 string    `gorm:"column:answer_68"`
	Answer_69 string    `gorm:"column:answer_69"`
	Answer_70 string    `gorm:"column:answer_70"`
	Answer_71 string    `gorm:"column:answer_71"`
	Answer_72 string    `gorm:"column:answer_72"`
	Answer_73 string    `gorm:"column:answer_73"`
	Answer_74 string    `gorm:"column:answer_74"`
	Answer_75 string    `gorm:"column:answer_75"`
	Answer_76 string    `gorm:"column:answer_76"`
	Answer_77 string    `gorm:"column:answer_77"`
	Answer_78 string    `gorm:"column:answer_78"`
	Answer_79 string    `gorm:"column:answer_79"`
	Answer_80 string    `gorm:"column:answer_80"`
	Answer_81 string    `gorm:"column:answer_81"`
	Answer_82 string    `gorm:"column:answer_82"`
	Answer_83 string    `gorm:"column:answer_83"`
	Answer_84 string    `gorm:"column:answer_84"`
	Answer_85 string    `gorm:"column:answer_85"`
	Answer_86 string    `gorm:"column:answer_86"`
	Answer_87 string    `gorm:"column:answer_87"`
	Answer_88 string    `gorm:"column:answer_88"`
	Answer_89 string    `gorm:"column:answer_89"`
	Answer_90 string    `gorm:"column:answer_90"`
	Answer_91 string    `gorm:"column:answer_91"`
	Answer_92 string    `gorm:"column:answer_92"`
	Answer_93 string    `gorm:"column:answer_93"`
	Result    string    `gorm:"column:result"`
}

func AddAnswer(testAnswerData TestAnswer) (error, TestAnswer,int) {
	testAnswerData.Test_time = time.Now().Local().Truncate(time.Microsecond)
	dbChain := db.Table("Test_answer_sheet").Select("sno", "Test_time", "answer_1", "answer_2", "answer_3", "answer_4",
		"answer_5", "answer_6", "answer_7", "answer_8", "answer_9", "answer_10", "answer_11", "answer_12", "answer_13", "answer_14", "answer_15",
		"answer_16", "answer_17", "answer_18", "answer_19", "answer_20", "answer_21", "answer_22", "answer_23", "answer_24", "answer_25",
		"answer_26", "answer_27", "answer_28", "answer_29", "answer_30", "answer_31", "answer_32", "answer_33", "answer_34", "answer_35",
		"answer_36", "answer_37", "answer_38", "answer_39", "answer_40", "answer_41", "answer_42", "answer_43", "answer_44", "answer_45",
		"answer_46", "answer_47", "answer_48", "answer_49", "answer_50", "answer_51", "answer_52", "answer_53", "answer_54", "answer_55",
		"answer_56", "answer_57", "answer_58", "answer_59", "answer_60", "answer_61", "answer_62", "answer_63", "answer_64", "answer_65",
		"answer_66", "answer_67", "answer_68", "answer_69", "answer_70", "answer_71", "answer_72", "answer_73", "answer_74", "answer_75",
		"answer_76", "answer_77", "answer_78", "answer_79", "answer_80", "answer_81", "answer_82", "answer_83", "answer_84", "answer_85",
		"answer_86", "answer_87", "answer_88", "answer_89", "answer_90", "answer_91", "answer_92", "answer_93").Create(&testAnswerData)
	var lastTestId uint64
	dbChain.Raw("SELECT nextval('baj_test_id_seq')").First(&lastTestId)
	return dbChain.Error, testAnswerData, int(lastTestId - 1)
}

func _UpdateMBTIAnswer(testAnswerData TestAnswer) (error, TestAnswer) {
	testAnswerData.Test_time = time.Now().Local().Truncate(time.Microsecond)
	dbChain := db.Table("Test_answer_sheet").Where("tas_id = ?", testAnswerData.Tas_id).Updates(&testAnswerData)
	return dbChain.Error, testAnswerData
}

func StoreTestAnswer(a *gin.Context) (error, TestAnswer, string) {
	var testAnswerData TestAnswer
	var result TestAnswer
	var total int64
	var id int
    var err error
	a.BindJSON(&testAnswerData)
	if testAnswerData.Tas_id > 0 {
		fmt.Println("修改测试结果")
		_UpdateMBTIAnswer(testAnswerData)
	} else {
		fmt.Println("增加测试结果")
		_, _, id = AddAnswer(testAnswerData)
		testAnswerData.Tas_id = id
	}
	var finalResult string
	// complete all 93 questions
	if testAnswerData.Answer_93 != "" {
		db.Table("Test_answer_sheet").Where("tas_id = ?", testAnswerData.Tas_id).Find(&result).Count(&total)
		finalResult = calculateFinalResult(result)
		fmt.Println("MBTI 答题结束，计算结果为: " + finalResult)
	}
	return err, testAnswerData, finalResult
}

func calculateFinalResult(testAnswerData TestAnswer) string {
	var answers = [...]string{
	    testAnswerData.Answer_1, testAnswerData.Answer_2, testAnswerData.Answer_3,
		testAnswerData.Answer_4, testAnswerData.Answer_5, testAnswerData.Answer_6,
		testAnswerData.Answer_7, testAnswerData.Answer_8, testAnswerData.Answer_9,
		testAnswerData.Answer_10, testAnswerData.Answer_11, testAnswerData.Answer_12,
		testAnswerData.Answer_13, testAnswerData.Answer_14, testAnswerData.Answer_15,
		testAnswerData.Answer_16, testAnswerData.Answer_17, testAnswerData.Answer_18,
		testAnswerData.Answer_19, testAnswerData.Answer_20, testAnswerData.Answer_21,
		testAnswerData.Answer_22, testAnswerData.Answer_23, testAnswerData.Answer_24,
		testAnswerData.Answer_25, testAnswerData.Answer_26, testAnswerData.Answer_27,
		testAnswerData.Answer_28, testAnswerData.Answer_29, testAnswerData.Answer_30,
		testAnswerData.Answer_31, testAnswerData.Answer_32, testAnswerData.Answer_33,
		testAnswerData.Answer_34, testAnswerData.Answer_35, testAnswerData.Answer_36,
		testAnswerData.Answer_37, testAnswerData.Answer_38, testAnswerData.Answer_39,
		testAnswerData.Answer_40, testAnswerData.Answer_41, testAnswerData.Answer_42,
		testAnswerData.Answer_43, testAnswerData.Answer_44, testAnswerData.Answer_45,
		testAnswerData.Answer_46, testAnswerData.Answer_47, testAnswerData.Answer_48,
		testAnswerData.Answer_49, testAnswerData.Answer_50, testAnswerData.Answer_51,
		testAnswerData.Answer_52, testAnswerData.Answer_53, testAnswerData.Answer_54,
		testAnswerData.Answer_55, testAnswerData.Answer_56, testAnswerData.Answer_57,
		testAnswerData.Answer_58, testAnswerData.Answer_59, testAnswerData.Answer_60,
		testAnswerData.Answer_61, testAnswerData.Answer_62, testAnswerData.Answer_63,
		testAnswerData.Answer_64, testAnswerData.Answer_65, testAnswerData.Answer_66,
		testAnswerData.Answer_67, testAnswerData.Answer_68, testAnswerData.Answer_69,
		testAnswerData.Answer_70, testAnswerData.Answer_71, testAnswerData.Answer_72,
		testAnswerData.Answer_73, testAnswerData.Answer_74, testAnswerData.Answer_75,
		testAnswerData.Answer_76, testAnswerData.Answer_77, testAnswerData.Answer_78,
		testAnswerData.Answer_79, testAnswerData.Answer_80, testAnswerData.Answer_81,
		testAnswerData.Answer_82, testAnswerData.Answer_83, testAnswerData.Answer_84,
		testAnswerData.Answer_85, testAnswerData.Answer_86, testAnswerData.Answer_87,
		testAnswerData.Answer_88, testAnswerData.Answer_89, testAnswerData.Answer_90,
		testAnswerData.Answer_91, testAnswerData.Answer_92, testAnswerData.Answer_93}

	var statisticRule map[string]int
	statisticRule = make(map[string]int)
	var finalResult string
	for i := 0; i < len(answers); i++ {
		statisticRule[answers[i]]++
	}
	if (statisticRule["I"] * 9) >= (statisticRule["E"] * 12) {
		finalResult += "I"
	} else {
		finalResult += "E"
	}
	if (statisticRule["N"] * 18) >= (statisticRule["S"] * 9) {
		finalResult += "N"
	} else {
		finalResult += "S"
	}
	if (statisticRule["F"] * 9) >= (statisticRule["T"] * 14) {
		finalResult += "F"
	} else {
		finalResult += "T"
	}
	if (statisticRule["P"] * 8) >= (statisticRule["J"] * 14) {
		finalResult += "P"
	} else {
		finalResult += "J"
	}
	testAnswerData.Result = finalResult
	_UpdateMBTIAnswer(testAnswerData)

	var studentInfo Student
	studentInfo.Sno = testAnswerData.Sno
	studentInfo.Mbti_outcome = finalResult
	UpdateByParam(studentInfo)
	return finalResult
}

func GetTestResult(testResultParam map[string]interface{}) (error, []TestAnswer) {
    searchSno := testResultParam["searchSno"];
	var testResultData []TestAnswer
	// show all test result
	if searchSno == "" {
	    err := db.Table("Test_answer_sheet").Select("sno", "Test_time", "answer_1", "answer_2", "answer_3", "answer_4",
             		"answer_5", "answer_6", "answer_7", "answer_8", "answer_9", "answer_10", "answer_11", "answer_12", "answer_13", "answer_14", "answer_15",
             		"answer_16", "answer_17", "answer_18", "answer_19", "answer_20", "answer_21", "answer_22", "answer_23", "answer_24", "answer_25",
             		"answer_26", "answer_27", "answer_28", "answer_29", "answer_30", "answer_31", "answer_32", "answer_33", "answer_34", "answer_35",
             		"answer_36", "answer_37", "answer_38", "answer_39", "answer_40", "answer_41", "answer_42", "answer_43", "answer_44", "answer_45",
             		"answer_46", "answer_47", "answer_48", "answer_49", "answer_50", "answer_51", "answer_52", "answer_53", "answer_54", "answer_55",
             		"answer_56", "answer_57", "answer_58", "answer_59", "answer_60", "answer_61", "answer_62", "answer_63", "answer_64", "answer_65",
             		"answer_66", "answer_67", "answer_68", "answer_69", "answer_70", "answer_71", "answer_72", "answer_73", "answer_74", "answer_75",
             		"answer_76", "answer_77", "answer_78", "answer_79", "answer_80", "answer_81", "answer_82", "answer_83", "answer_84", "answer_85",
             		"answer_86", "answer_87", "answer_88", "answer_89", "answer_90", "answer_91", "answer_92", "answer_93").Find(&testResultData).Error
        return err, testResultData
	}else {
	// show test result based on the searchSno
	    err := db.Table("Test_answer_sheet").Select("sno", "Test_time", "answer_1", "answer_2", "answer_3", "answer_4",
             		"answer_5", "answer_6", "answer_7", "answer_8", "answer_9", "answer_10", "answer_11", "answer_12", "answer_13", "answer_14", "answer_15",
             		"answer_16", "answer_17", "answer_18", "answer_19", "answer_20", "answer_21", "answer_22", "answer_23", "answer_24", "answer_25",
             		"answer_26", "answer_27", "answer_28", "answer_29", "answer_30", "answer_31", "answer_32", "answer_33", "answer_34", "answer_35",
             		"answer_36", "answer_37", "answer_38", "answer_39", "answer_40", "answer_41", "answer_42", "answer_43", "answer_44", "answer_45",
             		"answer_46", "answer_47", "answer_48", "answer_49", "answer_50", "answer_51", "answer_52", "answer_53", "answer_54", "answer_55",
             		"answer_56", "answer_57", "answer_58", "answer_59", "answer_60", "answer_61", "answer_62", "answer_63", "answer_64", "answer_65",
             		"answer_66", "answer_67", "answer_68", "answer_69", "answer_70", "answer_71", "answer_72", "answer_73", "answer_74", "answer_75",
             		"answer_76", "answer_77", "answer_78", "answer_79", "answer_80", "answer_81", "answer_82", "answer_83", "answer_84", "answer_85",
             		"answer_86", "answer_87", "answer_88", "answer_89", "answer_90", "answer_91", "answer_92", "answer_93").Where("sno = ?", searchSno).Find(&testResultData).Error
        return err, testResultData
	}
}
